package com.apes.fn.scm.retailOrder.service.account.retailReturn;

import com.apes.fn.scm.retailOrder.model.RetailOrder;
import com.apes.fn.scm.retailOrder.model.RetailOrderItem;
import com.apes.fn.scm.retailOrder.repository.RetailOrderItemRepository;
import com.apes.fn.scm.retailOrder.service.account.RetailReturnVoucher;
import com.apes.fn.scm.retailReturn.RetailReturn;
import com.apes.framework.jpa.spec.JpaDsl;
import com.apes.scm.account.account.model.AccountingMethod;
import com.apes.scm.account.account.model.InventoryMode;
import com.apes.scm.voucher.model.Voucher;
import com.apes.scm.voucher.model.VoucherItem;
import com.apes.scm.voucher.repository.VoucherRepository;
import com.apes.scm.voucher.service.BusinessType;
import com.apes.scm.voucher.service.VoucherType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @Author wuq
 * @Date 2021-11-22
 */
@RetailReturnAccount(value = "returnWithOrder", name = "零售有单退货生成销售退回凭证")
@Service
public class RetailReturnWithOrderVoucherService implements RetailReturnVoucher {

    @Autowired
    private VoucherRepository voucherRepository;
    @Autowired
    private RetailOrderItemRepository retailOrderItemRepository;

    @Override
    public Voucher process(RetailReturn retailReturn) {
        Voucher voucher = new Voucher();
        voucher.setReturned(true);
        voucher.setBusinessType(BusinessType.SALE_RETURN);
        voucher.setInventoryMode(InventoryMode.IM_OWN);     //设置库存模式：自有经销
        voucher.setAccountingMethod(AccountingMethod.AM_PURCHASE);  // 核算方式：采购
        voucher.setCustomerExpand(retailReturn.getCustomerExpand().getId());

        // 主表信息
        voucher.setCompany(retailReturn.getDept().getCompany());
        voucher.setDept(retailReturn.getDept());
        voucher.setClerk(retailReturn.getClerk()); //业务员

        voucher.setScene(retailReturn.getScene());
        voucher.setOrigin(retailReturn.getId());
        voucher.setOriginBusinessType(retailReturn.getInnerBusinessType());
        voucher.setSource(retailReturn.getId());
        voucher.setSourceBusinessType(retailReturn.getInnerBusinessType());

        // 增加凭证分类
        if ("RO003".equals(retailReturn.getSaleOrder().getScene().getId())) {
            voucher.setClassification(VoucherType.ENTRUST_LOSS);    // 委托定损
        }

        Voucher source = findVoucher(retailReturn.getSaleOrder().getId());
        if (source == null) throw new RuntimeException("没有找到原单：" + retailReturn.getSaleOrder().getId() + " 的业务凭证！");
        voucher.setVoucher(source);
        voucher.setPartner(source.getPartner());    // 赋值原销售客户

        // 明细数据
        voucher.setVoucherItems(getItems(retailReturn, voucher));
        return voucher;
    }

    private Voucher findVoucher(String businessId) {
        String businessType = RetailOrder.class.getSimpleName();
        List<Voucher> vouchers = voucherRepository.findAll(
                JpaDsl.toCriteriaByEq("originBusinessType", businessType, "origin", businessId, "source", businessId, "voucherType", "CUSTOMER_SALE"))
                .stream().filter(v -> !Objects.equals(VoucherType.E_MAINTAIN, v.getClassification())).collect(Collectors.toList());
        if (vouchers.size() > 1) throw new RuntimeException("根据源单据查询到多个分销凭证！请检查业务凭证！");

        Voucher voucher = vouchers.stream().findFirst().orElse(null);
        if (voucher == null) {
            voucher = voucherRepository.findOne(
                    JpaDsl.toCriteriaByEq("sourceBusinessType", businessType, "source", businessId, "voucherType", "CUSTOMER_SALE")).orElse(null);
        }
        return voucher;
    }

    private Set<VoucherItem> getItems(RetailReturn saleReturn, Voucher voucher) {
        Set<VoucherItem> voucherItems = new HashSet();
        saleReturn.getSaleItems().forEach(
                saleReturnItem -> {
                    VoucherItem voucherItem = new VoucherItem();
                    voucherItem.setVoucher(voucher);
                    voucherItem.setOwner(saleReturnItem.getOwner());

                    voucherItem.setProduct(saleReturnItem.getProduct());
                    voucherItem.setUom(saleReturnItem.getUom());
                    voucherItem.setProductQty(-1.00 * saleReturnItem.getProductUomQty());

                    voucherItem.setOriginItemId(saleReturnItem.getId());
                    voucherItem.setSourceItemId(String.valueOf(saleReturnItem.getId()));
                    voucherItem.setSupplier(saleReturnItem.getSupplier());

                    VoucherItem source = voucherItem.findVoucherItem(saleReturnItem.getRetailOrderItem().getId());
                    if (source == null) throw new RuntimeException("没有找到原单明细：" + saleReturnItem.getRetailOrderItem().getId() + " 的业务凭证！");
                    voucherItem.setVoucherItem(source);

                    voucherItem.setTax(source.getTax());
                    voucherItem.setPriceUnit(source.getPriceUnit());     // 获取原销售价格

                    // 折扣由于APP退的时候退到了一个商品上面，所以这里根据零售退货的明细找到对应的 负零售单明细上面的折扣
                    // 关联关系，负零售明细上面的 originnumber 为 零售退货明细的 Id
                    RetailOrderItem retailOrderItem = retailOrderItemRepository.findOne(
                            JpaDsl.toCriteriaByEq("order.id", saleReturn.getId(), "product.id", saleReturnItem.getProduct().getId(), "originnumber", saleReturnItem.getId()))
                            .orElseThrow(() -> new RuntimeException("零售退货根据【"+saleReturnItem.getProduct().getId()+"】商品以及来源单据行号【"+saleReturnItem.getId()+"】未找到负零售明细"));
                    voucherItem.setDiscount(retailOrderItem.getDiscountAmount());
                    voucherItems.add(voucherItem);
                });
        return voucherItems;
    }

}
